home *** CD-ROM | disk | FTP | other *** search
- /*
- ** SETVOL.C - set, change, or kill a disk volume label
- **
- ** public domain demo by Bob Stout
- ** DOS 5 enhancements suggested by Keith Beedle
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <dos.h>
- #include <io.h>
- #include "portable.h" /* Also in SNIPPETS */
-
- #define NUL '\0'
-
- #if defined(__TURBOC__)
- #pragma option -a-
- #include <dir.h>
- #include <io.h>
- #define _A_VOLID FA_LABEL
- #define _far far
- #else
- #include <direct.h>
- #if defined(__ZTC__)
- #pragma ZTC align 1
- #else /* MSC/QC/WATCOM/METAWARE */
- #pragma pack(1)
- #endif
- struct fcb {
- char fcb_drive;
- char fcb_name[8];
- char fcb_ext[3];
- short fcb_curblk;
- short fcb_recsize;
- long fcb_filsize;
- short fcb_date;
- char fcb_resv[10];
- char fcb_currec;
- long fcb_random;
- };
-
- struct xfcb {
- char xfcb_flag;
- char xfcb_resv[5];
- char xfcb_attr;
- struct fcb xfcb_fcb;
- };
- #endif
-
- #include "dos5boot.h" /* SNIPPETS file with DOS 5 boot record structure */
-
- /*
- ** NOTE: The following use functions in four other SNIPPETS files,
- ** ABSDISK.ASM, ABSDISKC.C, DRVALID.C, and PUSHDIR.C
- */
-
- int AbsDiskRead(unsigned short, size_t, size_t, void *);
- int AbsDiskWrite(unsigned short, size_t, size_t, void *);
- int getdrv(void);
- int PushDir(char *);
- int PopDir(void);
-
- /*
- ** Erase an existing volume label
- */
-
- void vol_kill(char *fname)
- {
- union REGS regs;
- struct SREGS sregs;
- struct xfcb buf;
-
- /* Parse the filename into an FCB */
-
- segread(&sregs);
- regs.h.ah = 0x29;
- regs.h.al = 0;
- regs.x.si = (unsigned)fname;
- regs.x.di = (unsigned)&buf.xfcb_fcb;
- sregs.es = sregs.ds;
- intdosx(®s, ®s, &sregs);
-
- /* Volume labels require extended FCB's */
-
- buf.xfcb_flag = 0xff;
- buf.xfcb_attr = _A_VOLID;
-
- /* Delete the old label */
-
- regs.h.ah = 0x13;
- regs.x.dx = (unsigned)&buf;
- intdos(®s, ®s);
- }
-
- /*
- ** Create a new volume label
- */
-
- void setvol(char *label)
- {
- char new_label[13]; /* name + ext + '.' + NUL */
- struct xfcb buf;
- union REGS regs;
- struct SREGS sregs;
- const char pattern[] = "????????";
- char _far *dta;
-
- /*
- ** Change to root directory.
- */
-
- PushDir("\\");
-
- /* If drive is already labeled, remove it */
-
- segread(&sregs);
- regs.h.ah = 0x2f;
- intdosx(®s, ®s, &sregs);
- dta = MK_FP(sregs.es, regs.x.bx);
-
- buf.xfcb_flag = 0xff;
- buf.xfcb_attr = _A_VOLID;
- buf.xfcb_fcb.fcb_drive = 0;
- memcpy(buf.xfcb_fcb.fcb_name, pattern, 8);
- memcpy(buf.xfcb_fcb.fcb_ext, pattern, 3);
-
- regs.h.ah = 0x11;
- regs.x.dx = (unsigned)&buf;
- intdos(®s, ®s);
-
- if (0 == regs.h.al)
- {
- int i;
- char oldlabel[13], _far *p, *q;
-
- for (i = 0, p = dta + 8, q =oldlabel; i < 8; ++i, ++p, ++q)
- {
- *q = *p;
- }
- *q++ = '.';
- for (i = 0, p = dta + 16; i < 3; ++i, ++p, ++q)
- {
- *q = *p;
- }
- vol_kill(oldlabel);
- }
-
- strcpy(new_label, label);
- if (8 < strlen(label))
- {
- new_label[8] = '.';
- strcpy(&new_label[9], &label[8]);
- }
-
- /* Parse the filename into an FCB */
-
- segread(&sregs);
- regs.h.ah = 0x29;
- regs.h.al = 0;
- regs.x.si = (unsigned)new_label;
- regs.x.di = (unsigned)&buf.xfcb_fcb;
- sregs.es = sregs.ds;
- intdosx(®s, ®s, &sregs);
-
- /* Volume labels require extended FCB's */
-
- buf.xfcb_flag = 0xff;
- buf.xfcb_attr = _A_VOLID;
-
- /* Create the new label */
-
- regs.h.ah = 0x16;
- regs.x.dx = (unsigned)&buf;
- intdos(®s, ®s);
-
- /* Close the new label */
-
- regs.h.ah = 0x10;
- regs.x.dx = (unsigned)&buf;
- intdos(®s, ®s);
-
- /*
- ** For DOS 5.0 replace the boot record too.
- */
-
- if(_osmajor > 3)
- {
- int index, drive = getdrv();
- B_REC boot_record;
-
- AbsDiskRead(drive, 1, 0, &boot_record);
- if(0 == strcmp(boot_record.bsOemName, "MSDOS5.0"))
- {
- index = 0;
- while (NUL != label[index])
- {
- boot_record.bsVolumeLabel[index] = label[index];
- index++;
- }
- for(index; index < 11; index++)
- boot_record.bsVolumeLabel[index] = 0x20;
- AbsDiskWrite(drive, 1, 0, &boot_record);
- }
- }
- PopDir();
- }
-
- #ifdef TEST
-
- main(int argc, char *argv[])
- {
- if (2 > argc)
- {
- puts("\aUsage: SETVOL new_name");
- abort();
- }
- setvol(argv[1]);
- return EXIT_SUCCESS;
- }
-
- #endif
-